package com.hbwxz.admin.service;

import com.hbwxz.admin.feign.ProductServiceClient;
import com.hbwxz.admin.pojo.*;
import com.hbwxz.admin.processor.RedisCommonProcessor;
import com.hbwxz.admin.repo.*;
import com.hbwxz.common.pojo.CommodityAttributes;
import com.hbwxz.common.pojo.CommodityEsBodyDeprecated;
import com.hbwxz.common.response.CommonResponse;
import com.hbwxz.common.response.ResponseCode;
import com.hbwxz.common.response.ResponseUtils;
import com.hbwxz.common.utils.JsonUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.transaction.Transactional;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class CommodityService {
    @Autowired
    private CommoditySkuRepository skuRepository;

    @Autowired
    private CommoditySpuRepository spuRepository;

    @Autowired
    private CommoditySpuDetailRepository spuDetailRepository;

    @Autowired
    private CommodityCategoryRepository commodityCategoryRepository;
    @Autowired
    private CommodityBrandRepository commodityBrandRepository;
    @Autowired
    private CommoditySpuDetailRepository commoditySpuDetailRepository;

    @Autowired
    private CommodityAttrRepository commodityAttrRepository;

    @Autowired
    private CommodityAttrGroupRepository commodityAttrGroupRepository;
    @Autowired
    private CommoditySpuRepository commoditySpuRepository;
    @Autowired
    private CommoditySkuRepository commoditySkuRepository;
    @Autowired
    private RedisCommonProcessor redisCommonProcessor;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private ProductServiceClient productServiceClient;

    @Autowired
    private CommoditySkuUpErrorRepository commoditySkuUpErrorRepository;
    @Transactional
    public void createCommodity(CommodityParam commodityParam) {
        Optional<CommodityCategory> cc = commodityCategoryRepository.findById(commodityParam.getCategoryId());
        if(!cc.isPresent()) {
            throw new RuntimeException("categoryId is invalid");
        }

        Optional<CommodityBrand> cb = commodityBrandRepository.findById(commodityParam.getBrandId());
        if(!cb.isPresent()) {
            throw new RuntimeException("brandId is invalid");
        }


        CommoditySpu commoditySpu = CommoditySpu.builder()
                .name(commodityParam.getName())
                .isSale(1)
                .brandId(commodityParam.getBrandId())
                .shopId(commodityParam.getShopId())
                .categoryId(commodityParam.getCategoryId())
                .createTime(new Date())
                .updateTime(new Date())
                .build();

        spuRepository.save(commoditySpu);

        CommoditySpuDetail commoditySpuDetail = commodityParam.getSpuDetail();
        commoditySpuDetail.setSpuId(commoditySpu.getId());
        commoditySpuDetail.setCreateTime(new Date());
        commoditySpuDetail.setUpdateTime(new Date());
        spuDetailRepository.save(commoditySpuDetail);

        Map<String,List<String>> speAttr = JsonUtils.readValue(commoditySpuDetail.getSpecificAttr(), Map.class);
        AtomicInteger pos = new AtomicInteger(0);
        List<CommoditySku> skus = commodityParam.getSkus().stream().map(sku->{
            sku.setSpuId(commoditySpu.getId());
            sku.setCreateTime(new Date());
            sku.setUpdateTime(new Date());
            Map<String,String> ownAttrMap = new HashMap<>();
            String[] indexes = sku.getIndexes().split("_");
            speAttr.keySet().forEach(key->{
                ownAttrMap.put(key,speAttr.get(key).get(Integer.valueOf(indexes[pos.getAndIncrement()])));
            });
            sku.setOwnAttr(JsonUtils.toJsonString(ownAttrMap));
            pos.set(0);
            sku.setIsValid(0);
            return sku;
        }).collect(Collectors.toList());
        skuRepository.saveAll(skus);

    }

    public CommoditySpuDetail getSpuDetail(Long spuId) {
        Optional<CommoditySpuDetail> optionalCommmoditySpuDetail = commoditySpuDetailRepository.findById(spuId);
        if(!optionalCommmoditySpuDetail.isPresent()) {
            return optionalCommmoditySpuDetail.get();
        }
        return null;
    }

    public List<CommoditySku> getSkuBySpuId(Long spuId) {
        List<CommoditySku> skus = skuRepository.getBySpuId(spuId);
        return skus;
    }

    public void updateCommodity(CommodityParam commodityParam) {
        checkCategoryAndBrand(commodityParam.getCategoryId(), commodityParam.getBrandId());
        Long spuId = commodityParam.getSpuDetail().getSpuId();
        Optional<CommoditySpu> spu = spuRepository.findById(spuId);
        if(spu.isPresent()) {
            CommoditySpu commoditySpu = CommoditySpu.builder()
                    .id(spu.get().getId())
                    .name(commodityParam.getName())
                    .isSale(1)
                    .brandId(commodityParam.getBrandId())
                    .shopId(commodityParam.getShopId())
                    .categoryId(commodityParam.getCategoryId())
                    .createTime(spu.get().getCreateTime())
                    .updateTime(spu.get().getUpdateTime())
                    .build();
            spuRepository.save(commoditySpu);
        }else{
            throw new RuntimeException("Error commodityParam!");
        }

        Optional<CommoditySpuDetail> spuDetail = spuDetailRepository.findById(spuId);
        if(spuDetail.isPresent()) {
            CommoditySpuDetail commoditySpuDetail = commodityParam.getSpuDetail();
            commoditySpuDetail.setSpuId(spuId);
            commoditySpuDetail.setCreateTime(spuDetail.get().getCreateTime());
            commoditySpuDetail.setUpdateTime(spuDetail.get().getUpdateTime());
            spuDetailRepository.save(commoditySpuDetail);
        }else{
            throw new RuntimeException("Error commodityParam!");
        }

        List<CommoditySku> oldSkus = skuRepository.getBySpuId(spuId);
        skuRepository.deleteAll(oldSkus);

        Date date = new Date();

        Map<String,List<String>> speAttr = JsonUtils.readValue(commodityParam.getSpuDetail().getSpecificAttr(), Map.class);
        AtomicInteger pos = new AtomicInteger(0);
        List<CommoditySku> skus = commodityParam.getSkus().stream().map(sku->{
            sku.setSpuId(spuId);
            sku.setCreateTime(date);
            sku.setUpdateTime(date);
            Map<String,String> ownAttrMap = new HashMap<>();
            String[] indexes = sku.getIndexes().split("_");
            speAttr.keySet().forEach(key->{
                ownAttrMap.put(key,speAttr.get(key).get(Integer.valueOf(indexes[pos.getAndIncrement()])));
            });
            sku.setOwnAttr(JsonUtils.toJsonString(ownAttrMap));
            pos.set(0);
            sku.setIsValid(0);
            return sku;
        }).collect(Collectors.toList());
        skuRepository.saveAll(skus);
    }

    private void checkCategoryAndBrand(Long cid,Long bid){
        Optional<CommodityCategory> cc = commodityCategoryRepository.findById(cid);
        if(!cc.isPresent()) {
            throw new RuntimeException("categoryId is invalid");
        }

        Optional<CommodityBrand> cb = commodityBrandRepository.findById(bid);
        if(!cb.isPresent()) {
            throw new RuntimeException("brandId is invalid");
        }
    }

    public void onSale(Long spuId) {
        Optional<CommoditySpu> spu = commoditySpuRepository.findById(spuId);
        Assert.isTrue(spu.isPresent(),"spu should not be null");
        Optional<CommoditySpuDetail> spuDetail = commoditySpuDetailRepository.findById(spuId);
        Assert.isTrue(spuDetail.isPresent(),"spuDetail should not be null");
        List<CommoditySku> skus = commoditySkuRepository.getBySpuId(spuId);
        Assert.notEmpty(skus,"spuId is invalid");
        Optional<CommodityBrand> brand = commodityBrandRepository.findById(spu.get().getBrandId());
        Assert.isTrue(brand.isPresent(),"brandId is invalid");
        Optional<CommodityCategory> category = commodityCategoryRepository.findById(spu.get().getCategoryId());
        Assert.isTrue(category.isPresent(),"categoryId is invalid");


        Map<String,String> genericAttr = JsonUtils.readValue(spuDetail.get().getGenericAttr(), Map.class);
        List< CommodityAttributes> attrs = new ArrayList<>();
        genericAttr.keySet().forEach(key->{
            Optional<CommodityAttr> attr = commodityAttrRepository.findById(Long.parseLong(key));
            Optional<CommodityAttrGroup> attrGroup = commodityAttrGroupRepository.findById(attr.get().getGroupId());
            CommodityAttributes commodityAttributes = CommodityAttributes.builder()
                    .attrId(attr.get().getId())
                    .attrName(attr.get().getName())
                    .attrGroupId(attrGroup.get().getId())
                    .attrGroupName(attrGroup.get().getName())
                    .attrValue(genericAttr.get(key))
                    .build();
            attrs.add(commodityAttributes);
        });

        List<CommodityEsBodyDeprecated>  esBodies = new ArrayList<>();
        skus.forEach(sku ->{
            Map<String,String> ownAttr = JsonUtils.readValue(sku.getOwnAttr(), Map.class);
            List<CommodityAttributes> skuAttrs = new ArrayList<>(attrs);
            ownAttr.keySet().forEach(key->{
                Optional<CommodityAttr> attr = commodityAttrRepository.findById(Long.parseLong(key));
                Optional<CommodityAttrGroup> attrGroup = commodityAttrGroupRepository.findById(attr.get().getGroupId());
                CommodityAttributes commodityAttributes = CommodityAttributes.builder()
                        .attrId(attr.get().getId())
                        .attrName(attr.get().getName())
                        .attrGroupId(attrGroup.get().getId())
                        .attrGroupName(attrGroup.get().getName())
                        .attrValue(ownAttr.get(key))
                        .build();
                skuAttrs.add(commodityAttributes);
            });

            CommodityEsBodyDeprecated commodityEsBodyDeprecated = CommodityEsBodyDeprecated.builder()
                    .brandId(spu.get().getBrandId())
                    .categoryId(spu.get().getCategoryId())
                    .spuId(spuId)
                    .skuId(sku.getId())
                    .price(sku.getPrice())
                    .brandName(brand.get().getName())
                    .categoryName(category.get().getName())
                    .image("todo")
                    .skuTitle(sku.getTitle())
                    .packingList(spuDetail.get().getPackingList())
                    .customerService(spuDetail.get().getCustomerService())
                    .attrs(skuAttrs)
                    .build();
            esBodies.add(commodityEsBodyDeprecated);
        });
        System.out.println(JsonUtils.toJsonString(esBodies));
    }

    @Deprecated
    public void onSale1(Long spuId) {
        Optional<CommoditySpu> spu = commoditySpuRepository.findById(spuId);
        Assert.isTrue(spu.isPresent(),"spu should not be null");
        Optional<CommoditySpuDetail> spuDetail = commoditySpuDetailRepository.findById(spuId);
        Assert.isTrue(spuDetail.isPresent(),"spuDetail should not be null");
        List<CommoditySku> skus = commoditySkuRepository.getBySpuId(spuId);
        Assert.notEmpty(skus,"spuId is invalid");
        Optional<CommodityBrand> brand = commodityBrandRepository.findById(spu.get().getBrandId());
        Assert.isTrue(brand.isPresent(),"brandId is invalid");
        Optional<CommodityCategory> category = commodityCategoryRepository.findById(spu.get().getCategoryId());
        Assert.isTrue(category.isPresent(),"categoryId is invalid");


        Map<String,String> genericAttr = JsonUtils.readValue(spuDetail.get().getGenericAttr(), Map.class);
        Map<String, CommodityAttributes> attrsCache = getAttrsCacheRedisson();
        List< CommodityAttributes> attrs = new ArrayList<>();
        genericAttr.keySet().forEach(key->{
            CommodityAttributes commodityAttributes = attrsCache.get(key);
            commodityAttributes.setAttrId(Long.parseLong(key));
            commodityAttributes.setAttrValue(genericAttr.get(key));
            attrs.add(commodityAttributes);
        });

        List<CommodityEsBodyDeprecated>  esBodies = new ArrayList<>();
        skus.forEach(sku ->{
            Map<String,String> ownAttr = JsonUtils.readValue(sku.getOwnAttr(), Map.class);
            List<CommodityAttributes> skuAttrs = new ArrayList<>(attrs);
            ownAttr.keySet().forEach(key->{
                CommodityAttributes commodityAttributes = attrsCache.get(key);
                commodityAttributes.setAttrId(Long.parseLong(key));
                commodityAttributes.setAttrValue(ownAttr.get(key));
                skuAttrs.add(commodityAttributes);
            });

            CommodityEsBodyDeprecated commodityEsBodyDeprecated = CommodityEsBodyDeprecated.builder()
                    .brandId(spu.get().getBrandId())
                    .categoryId(spu.get().getCategoryId())
                    .spuId(spuId)
                    .skuId(sku.getId())
                    .price(sku.getPrice())
                    .brandName(brand.get().getName())
                    .categoryName(category.get().getName())
                    .image("todo")
                    .skuTitle(sku.getTitle())
                    .packingList(spuDetail.get().getPackingList())
                    .customerService(spuDetail.get().getCustomerService())
                    .attrs(skuAttrs)
                    .build();
            esBodies.add(commodityEsBodyDeprecated);
        });
        System.out.println(JsonUtils.toJsonString(esBodies));
    }

    @Deprecated //减少db的io次数
    public void onSale2(Long spuId) {
        List<Map<String,Object>> esBodies = commoditySpuRepository.getCommodityBySpuId(spuId);
        List<CommodityEsBodyDeprecated> results = new ArrayList<>();
        if(esBodies == null || esBodies.size() == 0) {
            return ;
        }

        Map<String, CommodityAttributes> attrsCache = getAttrsCacheRedisson();
        List< CommodityAttributes> commonAttrs = new ArrayList<>();
        for (Map<String,Object> esBody : esBodies) {
            CommodityEsBodyDeprecated commodityEsBodyDeprecated = JsonUtils.readValue(JsonUtils.toJsonString(esBody), CommodityEsBodyDeprecated.class);
            if(commonAttrs.size() == 0) {
                //因为是公共的 所以取第一个
                Map<String, String> genericAttr = JsonUtils.readValue(commodityEsBodyDeprecated.getGenericAttrs(), Map.class);
                genericAttr.keySet().forEach(key -> {
                    CommodityAttributes commodityAttributes = attrsCache.get(key);
                    commodityAttributes.setAttrId(Long.parseLong(key));
                    commodityAttributes.setAttrValue(genericAttr.get(key));
                    commonAttrs.add(commodityAttributes);
                });
            }
            List<CommodityAttributes> attrs = new ArrayList<>(commonAttrs);
            Map<String,String> ownAttr = JsonUtils.readValue(commodityEsBodyDeprecated.getOwnAttr(), Map.class);
            ownAttr.keySet().forEach(key->{
                CommodityAttributes commodityAttributes = attrsCache.get(key);
                attrs.add(CommodityAttributes.builder()
                .attrId(Long.parseLong(key))
                        .attrValue(ownAttr.get(key))
                                .attrName(commodityAttributes.getAttrName())
                        .attrGroupId(commodityAttributes.getAttrGroupId())
                        .attrGroupName(commodityAttributes.getAttrGroupName()).build());
            });
            commodityEsBodyDeprecated.setAttrs(attrs);
            commodityEsBodyDeprecated.setOwnAttr(null);
            commodityEsBodyDeprecated.setGenericAttrs(null);
            results.add(commodityEsBodyDeprecated);
        }
        System.out.println(JsonUtils.toJsonString(results));
    }

    @Deprecated //冲破 不成文的代码规范
    public List<Map<String,Object>> onSale3(Long spuId) {
        List<Map<String,Object>> esBodies = commoditySpuRepository.getCommodityBySpuId(spuId);
        List<Map<String,Object>> result = new ArrayList<>();

        if(esBodies == null || esBodies.size() == 0) {
            return result;
        }

        Map<String, CommodityAttributes> attrsCache = getAttrsCacheRedisson();
        List< CommodityAttributes> commonAttrs = new ArrayList<>();
        for (Map<String,Object> esBody : esBodies) {
            CommodityEsBodyDeprecated commodityEsBodyDeprecated = JsonUtils.readValue(JsonUtils.toJsonString(esBody), CommodityEsBodyDeprecated.class);
            if(commonAttrs.size() == 0) {
                //因为是公共的 所以取第一个
                Map<String, String> genericAttr = JsonUtils.readValue(esBody.get("genericAttrs").toString(), Map.class);
                genericAttr.keySet().forEach(key -> {
                    CommodityAttributes commodityAttributes = attrsCache.get(key);
                    commodityAttributes.setAttrId(Long.parseLong(key));
                    commodityAttributes.setAttrValue(genericAttr.get(key));
                    commonAttrs.add(commodityAttributes);
                });
            }
            List<CommodityAttributes> attrs = new ArrayList<>(commonAttrs);
            Map<String,String> ownAttr = JsonUtils.readValue(esBody.get("ownAttr").toString(), Map.class);
            ownAttr.keySet().forEach(key->{
                CommodityAttributes commodityAttributes = attrsCache.get(key);
                attrs.add(CommodityAttributes.builder()
                        .attrId(Long.parseLong(key))
                        .attrValue(ownAttr.get(key))
                        .attrName(commodityAttributes.getAttrName())
                        .attrGroupId(commodityAttributes.getAttrGroupId())
                        .attrGroupName(commodityAttributes.getAttrGroupName()).build());
            });
            Map<String,Object> newMap = new HashMap<>(esBody);
            newMap.put("attrs", attrs);
            result.add(newMap);
        }
        return result;
    }

    public CommonResponse onSale4(Long spuId) {
        //1.查询Db 获取所有的sku信息
        List<Map<String,Object>> esBodies = commoditySpuRepository.getCommodityBySpuId(spuId);
        if(esBodies == null || esBodies.size() == 0) {
            return ResponseUtils.okResponse(null);
        }
        //2. 组装column
        Map<String,Object> result = new HashMap<>();
        List<Object> columns = generateColumns(esBodies);
        result.put("columns",columns);

        // 3.组装commonAttrs
        List<CommodityAttributes> commonAttrs = generateAttrs(esBodies.get(0),"genericAttrs");
        result.put("commonAttrs",commonAttrs);
        //4.组装values
        int skuIdIndex = columns.indexOf("skuId");
        List<Object> skuIds = new ArrayList<>();
        List<Object> values = generateValues(esBodies,columns,skuIds,skuIdIndex);
        result.put("values",values);
        //5.处理值及其补偿机制
        return responseHandler(result,skuIds);
    }

    private CommonResponse responseHandler(Map<String, Object> result, List<Object> skuIds) {
        CommonResponse response = productServiceClient.onSaleToEs(result);
        if(response.getCode() == ResponseCode.SUCCESS.getCode()) {
            try {
                commoditySkuRepository.updateSkuOnSaleStatus(skuIds);
            } catch (Exception e) {
                errorRetryHandle(skuIds);
            }
            return ResponseUtils.okResponse(null);
        }else if(response.getCode() == ResponseCode.BAD_ESBULK_REQUEST.getCode()){
            List<String> failedSkuIds = JsonUtils.readValueFromObject(response.getContent(), List.class);
            List<Object> diffList = null;
            try {
                //找到成功的id 去上架
                diffList = skuIds.stream()
                        .filter(skuId -> !failedSkuIds.contains(skuId.toString()))
                        .collect(Collectors.toList());
                commoditySkuRepository.updateSkuOnSaleStatus(diffList);
            } catch (Exception e) {
                errorRetryHandle(skuIds);
            }
            return ResponseUtils.failResponse(ResponseCode.BAD_ESBULK_REQUEST.getCode(), failedSkuIds,ResponseCode.BAD_ESBULK_REQUEST.getMessage());
        }
        return response;
    }

    private void errorRetryHandle(List<Object> skuIds) {
        List<CommoditySkuUpError> skuUpErrors =  new ArrayList<>();
        skuIds.forEach(skuId ->{
            skuUpErrors.add(CommoditySkuUpError.builder().skuId(Integer.parseInt(skuId.toString())).epoch(0).status(0).build());
        });
        commoditySkuUpErrorRepository.saveAll(skuUpErrors);
    }

    private List<Object> generateValues(List<Map<String, Object>> esBodies, List<Object> columns, List<Object> skuIds, int skuIdIndex) {
        List<Object> values = new ArrayList<>();
        esBodies.forEach(body->{
            List<Object> valueList = new ArrayList<>();
            columns.forEach(col ->{
                valueList.add(body.get(col));
            });
            skuIds.add(valueList.get(skuIdIndex));
            List<CommodityAttributes> attrs = generateAttrs(body,"ownAttr");
            valueList.set(valueList.size()-1, attrs);
            values.add(valueList);
        });
        return values;
    }

    private List<CommodityAttributes> generateAttrs(Map<String, Object> body, String attrKey) {
        Map<String, CommodityAttributes> attrsCache = getAttrsCacheRedisson();
        List< CommodityAttributes> commonAttrs = new ArrayList<>();
        //因为是公共的 所以取第一个
        Map<String, String> attrs = JsonUtils.readValue(body.get(attrKey).toString(), Map.class);
        attrs.keySet().forEach(key -> {
            CommodityAttributes commodityAttributes = attrsCache.get(key);
            commonAttrs.add(CommodityAttributes.builder()
                    .attrGroupId(commodityAttributes.getAttrGroupId())
                    .attrGroupName(commodityAttributes.getAttrGroupName())
                            .attrId(Long.parseLong(key))
                            .attrValue(attrs.get(key))
                    .build()
            );
        });
        return commonAttrs;
    }

    private List<Object> generateColumns(List<Map<String, Object>> esBodies) {
        List<Object> column = esBodies.get(0).keySet().stream().collect(Collectors.toList());
        column.remove("ownAttr");
        column.remove("genericAttrs");
        column.add("attrs");
        return column;
    }

    private Map<String,CommodityAttributes> getAttrsCache(){
        Object cache = redisCommonProcessor.get("attrsCache");
        if(cache != null){
            return (Map<String,CommodityAttributes>)cache;
        }
        Map<String,CommodityAttributes> attrsCache = new HashMap<>();
        List<CommodityAttr> attrs = commodityAttrRepository.findAll();
        attrs.forEach(attr->{
            Optional<CommodityAttrGroup> attrGroup = commodityAttrGroupRepository.findById(attr.getGroupId());
            CommodityAttributes commodityAttributes = CommodityAttributes.builder()
                    .attrName(attr.getName())
                    .attrGroupId(attrGroup.get().getId())
                    .attrGroupName(attrGroup.get().getName())
                    .build();
            attrsCache.put(attr.getId().toString(),commodityAttributes);
        });
        redisCommonProcessor.set("attrsCache",attrsCache);
        return attrsCache;
    }

    @Deprecated
    private Map<String,CommodityAttributes> getAttrsCacheRedisSetNx(){
        Object cache = redisCommonProcessor.get("attrsCache");
        if(cache != null){
            return (Map<String,CommodityAttributes>)cache;
        }
        String uuid = UUID.randomUUID().toString();
        if(redisCommonProcessor.getLock("attrsCacheLock",uuid,60, TimeUnit.SECONDS)){
            try {
                Map<String,CommodityAttributes> attrsCache = new HashMap<>();
                List<CommodityAttr> attrs = commodityAttrRepository.findAll();
                attrs.forEach(attr->{
                    Optional<CommodityAttrGroup> attrGroup = commodityAttrGroupRepository.findById(attr.getGroupId());
                    CommodityAttributes commodityAttributes = CommodityAttributes.builder()
                            .attrName(attr.getName())
                            .attrGroupId(attrGroup.get().getId())
                            .attrGroupName(attrGroup.get().getName())
                            .build();
                    attrsCache.put(attr.getId().toString(),commodityAttributes);
                });
                redisCommonProcessor.set("attrsCache",attrsCache);
                return attrsCache;
            } finally {
                //unlock
                String luaScripts = "if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
                Long res = redisCommonProcessor.runLuaScripts(luaScripts, uuid, "attrsCacheLock");
                System.out.println("del result" + res);
            }
        }else{
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return getAttrsCacheRedisSetNx();
        }
    }

    private Map<String,CommodityAttributes> getAttrsCacheRedisson(){
        Object cache = redisCommonProcessor.get("attrsCache");
        if(cache != null){
            return (Map<String,CommodityAttributes>)cache;
        }
        RLock lock = redissonClient.getLock("attrsCacheLock");
        lock.lock(10, TimeUnit.SECONDS);//10s过期 不会续期
        try {
            if(cache != null){
                return (Map<String,CommodityAttributes>)redisCommonProcessor.get("attrsCache");
            }
            Map<String,CommodityAttributes> attrsCache = new HashMap<>();
            List<CommodityAttr> attrs = commodityAttrRepository.findAll();
            attrs.forEach(attr->{
                Optional<CommodityAttrGroup> attrGroup = commodityAttrGroupRepository.findById(attr.getGroupId());
                CommodityAttributes commodityAttributes = CommodityAttributes.builder()
                        .attrName(attr.getName())
                        .attrGroupId(attrGroup.get().getId())
                        .attrGroupName(attrGroup.get().getName())
                        .build();
                attrsCache.put(attr.getId().toString(),commodityAttributes);
            });
            redisCommonProcessor.set("attrsCache",attrsCache);
            return attrsCache;
        } catch (Exception e) {
            throw new UnsupportedOperationException("get attrs cache failed with exception"+e);
        } finally {
            try {
                lock.unlock();
            } catch (Exception e) {
                System.out.println("打印warninng日志即可");
            }
        }

    }
}
